﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using ImportSales.Ftp;
using System.Configuration;
using System.IO;
using ImportArticles.Process;

namespace ImportArticles
{
    class Program
    {
        public const string FTPServerKey = "FTPServer";
        public const string FTPUserKey = "FTPUser";
        public const string FTPPasswordKey = "FTPPassword";
        public const string FTPDirectoryKey = "FTPDirectory";
        public const string ConnectionStringKey = "default";
        public const string LocalTmpDirectoryKey = "LocalTmpDirectory";
        public const string DeleteFromLocalTmpDirectoryKey = "DeleteFromLocalTmpDirectory";
        public const string CompanyId = "CompanyId";

        static void Main(string[] args)
        {
            try
            {
                LoadLogFile(DateTime.Now);
                string ftpDirectory = ConfigurationManager.AppSettings[FTPDirectoryKey];
                string tmpDirectory = ConfigurationManager.AppSettings[LocalTmpDirectoryKey];
                bool deleteFromTmpDirectory = bool.Parse(ConfigurationManager.AppSettings[DeleteFromLocalTmpDirectoryKey]);
                int empresaId = Convert.ToInt32(ConfigurationManager.AppSettings[CompanyId]);

                List<string> archivosAProcesar = new List<string>();

                UploadArticlesIntoDb importProcess = new UploadArticlesIntoDb();
                importProcess.ConnectionString = ConfigurationManager.ConnectionStrings[ConnectionStringKey].ConnectionString;
                importProcess.Notify += new UploadArticlesIntoDb.Notificar(importProcess_Notify);

                if (args.Length > 0)
                {
                    Log("Procesando Artículos de Brasil - Arhivo de parámetro");
                    importProcess.InputFilePath = args[0];

                    if (args.Length > 1)
                    {
                        importProcess.StartLineNumber = Convert.ToDecimal(args[1]);
                    }

                    importProcess.EmpresaId = empresaId;

                    importProcess.DoImport();
                }
                else
                {
                    if (!String.IsNullOrEmpty(ftpDirectory))
                    {
                        Log("Procesando ventas de Brasil - Archivos del FTP");
                        FtpProcess ftpProcess = new FtpProcess();
                        ftpProcess.FTPServer = ConfigurationManager.AppSettings[FTPServerKey];
                        ftpProcess.FTPUser = ConfigurationManager.AppSettings[FTPUserKey];
                        ftpProcess.FTPPassword = ConfigurationManager.AppSettings[FTPPasswordKey];

                        archivosAProcesar.AddRange(ftpProcess.GetFilesFromDirectory(ftpDirectory));

                        foreach (string fileInFtp in archivosAProcesar)
                        {
                            string directoryfileInFtp = ftpDirectory + "/" + fileInFtp;
                            string destinationPath = Path.Combine(tmpDirectory, fileInFtp);

                            Log(String.Format("Bajando archivo {0}", directoryfileInFtp));
                            ftpProcess.DownLoadFile(directoryfileInFtp, destinationPath);

                            Log("Procesando Archivo");
                            importProcess.EmpresaId = empresaId;
                            importProcess.InputFilePath = destinationPath;
                            importProcess.DoImport();

                            Log(String.Format("Borrando archivo del sistema de archivos {0}", destinationPath));
                            File.Delete(destinationPath);

                            Log(String.Format("Borrando archivo del FTP", directoryfileInFtp));
                            ftpProcess.DeleteFile(directoryfileInFtp);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string message = GetExceptionMessage(ex);
                string stack = GetExceptionStackTrace(ex);

                Log(message + stack);
            }
        }

        static void importProcess_Notify(string mensaje)
        {
            Log(mensaje);
        }

        private static void Log(string message)
        {
            if (!String.IsNullOrEmpty(LogFilePath))
            {
                using (StreamWriter writer = File.AppendText(LogFilePath))
                {
                    writer.WriteLine(message);
                    writer.Close();
                }
            }
        }

        private static string LogFilePath = string.Empty;

        private static void LoadLogFile(DateTime fechaLog)
        {
            string filePath = ConfigurationManager.AppSettings["LogFilePath"];
            if (!String.IsNullOrEmpty(filePath))
            {
                if (!Directory.Exists(filePath))
                {
                    Directory.CreateDirectory(filePath);
                }

                // Creo archivo para logear
                filePath = Path.Combine(filePath, fechaLog.ToString("yyyyMMdd"));

                int i = 1;
                string original = filePath;
                while (File.Exists(filePath))
                {
                    filePath = original + "_" + i.ToString();
                    i++;
                }

                LogFilePath = filePath;
            }
        }

        public static string GetExceptionMessage(Exception ex)
        {
            StringBuilder builder = new StringBuilder();

            Exception current = ex;
            while (current != null)
            {
                builder.Append(current.Message);
                current = current.InnerException;
            }

            return builder.ToString();
        }

        public static string GetExceptionStackTrace(Exception ex)
        {
            StringBuilder builder = new StringBuilder();

            Exception current = ex;
            while (current != null)
            {
                builder.Append(current.StackTrace);
                current = current.InnerException;
            }

            return builder.ToString();
        }
    }
}
